﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.Serialization.Json;
using System.Security.Cryptography;
using System.Text;
using System.Web;
using System.Xml;

namespace ApiCoreProject.Api
{
    public class Tools
    {
        /// <summary>
        /// Md5加密，返回32位的字符串
        /// </summary>
        /// <param name="input"></param>
        /// <param name="type">返回值大小写，默认x2，小写，大写是X2</param>
        /// <returns></returns>
        public static string Md5(string input, string type = "x2")
        {
            MD5 md5 = MD5.Create();

            byte[] bytes = Encoding.Default.GetBytes(input);

            byte[] bytesMd5 = md5.ComputeHash(bytes);

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < bytesMd5.Length; i++)
            {
                sb.Append(bytesMd5[i].ToString(type));
            }

            return sb.ToString();
        }

        /// <summary>
        /// 验证服务器的请求
        /// </summary>
        /// <param name="signature">签名</param>
        /// <param name="timestamp"></param>
        /// <param name="nonce"></param>
        /// <param name="token">token</param>
        /// <returns></returns>
        public static bool CheckSignature(string signature, string timestamp, string nonce, string token)
        {

            List<string> list = new List<string>();
            list.Add(token);
            list.Add(timestamp);
            list.Add(nonce);
            //排序
            list.Sort();
            //拼串
            string input = string.Empty;
            foreach (var item in list)
            {
                input += item;
            }
            //加密
            string new_signature = Tools.SHA1Encrypt(input);
            //验证
            if (new_signature == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// SHA1加密
        /// </summary>
        /// <param name="intput">输入字符串</param>
        /// <returns>加密后的字符串</returns>
        public static string SHA1Encrypt(string intput)
        {
            byte[] StrRes = Encoding.Default.GetBytes(intput);
            HashAlgorithm mySHA = new SHA1CryptoServiceProvider();
            StrRes = mySHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte Byte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", Byte);
            }
            return EnText.ToString();
        }

        #region 获取公众号的AccessToken
        /// <summary>
        /// 获取公众号的AccessToken
        /// </summary>
        /// <returns></returns>
        //public static string GetAccessToken()
        //{  
        //    try
        //    {
        //        //先去读缓存
        //        var accessToken = "";//CacheHelper.GetCache("access_token");
        //        if (accessToken != null)
        //        {
        //            return accessToken.ToString();
        //        }
        //        var appid = Config.WeAppID;//注册公众号的时候分配的Id
        //        var appsecret = Config.WeAppSecret;//对应的密钥。
        //        string requestUrl =Config.access_token_url.Replace("APPID", appid).Replace("APPSECRET", appsecret);
        //        WebResponse result = null;
        //        WebRequest req = WebRequest.Create(requestUrl);
        //        result = req.GetResponse();
              
        //          Stream s = result.GetResponseStream();
        //        XmlDictionaryReader xmlReader = JsonReaderWriterFactory.CreateJsonReader(s, XmlDictionaryReaderQuotas.Max);
        //        xmlReader.Read();
               
        //        string xml = xmlReader.ReadOuterXml();
        //        s.Close();
        //        s.Dispose();
             
        //        XmlDocument doc = new XmlDocument();
        //        doc.LoadXml(xml);
               
        //        XmlElement rootElement = doc.DocumentElement;          
        //        string access_token = rootElement.SelectSingleNode("access_token").InnerText.Trim();
        //        CacheHelper.SetCache("access_token", access_token, 7000);//微信端默认是两小时过期，我们提前一点过期去获取新的
        //        return access_token;
        //    }catch(Exception ex)
        //    {
        //        return  ex.Message;
        //    }


        //}

        #endregion

        #region 获取公众号的jsapi_ticket
        /// <summary>
        /// 获取公众号的jsapi_ticket
        /// </summary>
        /// <returns></returns>
        //public static string GetTicket()
        //{
        //    //先去读缓存
        //    var jsapi_ticket = CacheHelper.GetCache("jsapi_ticket");
            
        //    if (jsapi_ticket == null)
        //    {
        //        var queryString = HttpUtility.ParseQueryString(string.Empty);
        //        queryString["access_token"] =Tools.GetAccessToken();
        //        queryString["type"] = "jsapi";

        //        var uri = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?" + queryString;
        //        var msg = Tools.WebRequestPostOrGet(uri, "");
        //        var jsonobj = Newtonsoft.Json.Linq.JObject.Parse(msg);

        //        CacheHelper.SetCache("jsapi_ticket", (string)jsonobj["ticket"], 7200);
        //        return jsonobj["ticket"].ToString();
        //    }

        //    return jsapi_ticket.ToString();


        //}

        #endregion

        //public static void CreateMenue(string appid, string appsecret)
        //{
        //    //获取access_token值
        //    string access_token = GetAccessToken();

        //    //根据access_token值
        //   var  createurl = Config.create_menu_url.Replace("ACCESS_TOKEN", access_token);
        //    string responeJsonStr = "{" +
        //         "\"button\":[" +
        //        "{\"name\":\"中秋系列\"," +
        //        "\"type\":\"click\"," +
        //        "\"key\":\"V1001_ZhongQiu\"" +
        //        "}" +
        //         ",{\"name\":\"摘星星\"," +
        //        "\"type\":\"click\"," +
        //        "\"key\":\"V1002_ZhaiXing\"" +
        //        "}" +
        //       "]" +
        //     "}";
        //    WebRequest req = WebRequest.Create(createurl);
        //    byte[] bytes = Encoding.UTF8.GetBytes(responeJsonStr.ToString());
        //    req.Method = "POST";
        //    req.ContentType = "application/x-www-form-urlencoded";
        //    req.ContentLength = bytes.Length;
        //    Stream reqStr = req.GetRequestStream();
        //    reqStr.Write(bytes, 0, bytes.Length);
        //    reqStr.Close();
        //}


        #region unix/datatime 时间转换
        /// <summary>
        /// unix时间转换为datetime
        /// </summary>
        /// <param name="timeStamp"></param>
        /// <returns></returns>
        public static DateTime UnixTimeToTime(string timeStamp)
        {
            DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
            long lTime = long.Parse(timeStamp + "0000000");
            TimeSpan toNow = new TimeSpan(lTime);
            return dtStart.Add(toNow);
        }

        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        public static int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }

        /**
* 生成时间戳，标准北京时间，时区为东八区，自1970年1月1日 0点0分0秒以来的秒数
* @return 时间戳
*/
        public static Int64 GenerateTimeStamp()
        {
            TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
            return Convert.ToInt64(ts.TotalSeconds);
        }
        #endregion

        #region Post/Get提交调用抓取
        /// <summary>
        /// Post/get 提交调用抓取
        /// </summary>
        /// <param name="url">提交地址</param>
        /// <param name="param">参数</param>
        /// <returns>string</returns>
        public static string WebRequestPostOrGet(string sUrl, string sParam)
        {
            byte[] bt = System.Text.Encoding.UTF8.GetBytes(sParam);

            Uri uriurl = new Uri(sUrl);
            HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uriurl);//HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + (url.IndexOf("?") > -1 ? "" : "?") + param);
            req.Method = "Post";
            req.Timeout = 120 * 1000;
            req.ContentType = "application/x-www-form-urlencoded;";
            req.ContentLength = bt.Length;

            using (Stream reqStream = req.GetRequestStream())//using 使用可以释放using段内的内存
            {
                reqStream.Write(bt, 0, bt.Length);
                reqStream.Flush();
            }
            try
            {
                using (WebResponse res = req.GetResponse())
                {
                    //在这里对接收到的页面内容进行处理 

                    Stream resStream = res.GetResponseStream();

                    StreamReader resStreamReader = new StreamReader(resStream, System.Text.Encoding.UTF8);

                    string resLine;

                    System.Text.StringBuilder resStringBuilder = new System.Text.StringBuilder();

                    while ((resLine = resStreamReader.ReadLine()) != null)
                    {
                        resStringBuilder.Append(resLine + System.Environment.NewLine);
                    }

                    resStream.Close();
                    resStreamReader.Close();

                    return resStringBuilder.ToString();
                }
            }
            catch (Exception ex)
            {
                return ex.Message;//url错误时候回报错
            }
        }
        #endregion Post/Get提交调用抓取

        #region 生成随机字符
        /// <summary>
        /// 生成随机字符
        /// </summary>
        /// <param name="iLength">生成字符串的长度</param>
        /// <returns>返回随机字符串</returns>
        public static string GetRandCode(int iLength=16)
        {
            string sCode = "";
            if (iLength == 0)
            {
                iLength = 4;
            }
            string codeSerial = "0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] arr = codeSerial.Split(',');
            int randValue = -1;
            Random rand = new Random(unchecked((int)DateTime.Now.Ticks));
            for (int i = 0; i < iLength; i++)
            {
                randValue = rand.Next(0, arr.Length - 1);
                sCode += arr[randValue];
            }
            return sCode;
        }
        #endregion

        #region 签名算法
        /// <summary>
        /// 签名算法
        /// </summary>
        /// <param name="ticket">ticket</param>
        /// <param name="noncestr">随机字符串</param>
        /// <param name="timestamp">时间戳</param>
        /// <param name="url"></param>
        /// <returns></returns>
        public static string GetSignature(string ticket, string noncestr, long timestamp, string url)
        {
            var string1Builder = new StringBuilder();
            //拼接字符串
            string1Builder.Append("jsapi_ticket=").Append(ticket).Append("&")
                          .Append("noncestr=").Append(noncestr).Append("&")
                          .Append("timestamp=").Append(timestamp).Append("&")
                          .Append("url=").Append(url.IndexOf("#") >= 0 ? url.Substring(0, url.IndexOf("#")) : url);
            string str = string1Builder.ToString();
            return SHA1Encrypt(str);//加密
        }

        #endregion 
    }


}